﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using GeneratorModels.Models;
using GeneratorModels.Properties;
using GeneratorModels.Utility;
using wintrue;

namespace GeneratorModels.Forms
{
    internal partial class Form_Main : WT_UI
    {
        private static DataBaseDAL DataBaseDALProp;
        internal static string ConnectionString = "";
        internal static string DataBaseString = "";
        internal static int DataBaseType = 0;
        internal static string ConnNamespace = "";
        internal static string ConnDBName = "";
        internal static string PackageName = "";
        private static string TemplatesPath = "Templates";
        private static string LogPath = "log";

        static Form_Main()
        {
            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + LogPath))
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + LogPath);
            if (!Directory.Exists(AppDomain.CurrentDomain.BaseDirectory + TemplatesPath))
                Directory.CreateDirectory(AppDomain.CurrentDomain.BaseDirectory + TemplatesPath);
        }

        internal Form_Main()
        {
            InitializeComponent();
            Icon = Resources.logo;
            label_DBConn.Text = "无连接！";
        }

        private void button_DBConn_Click(object sender, EventArgs e)
        {
            try
            {
                if (button_DBConn.Text.Equals("断  开"))
                {
                    if (MessageBox.Show("是否确定要断开连接？", "断开连接确认", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        listView_SourceTable.Clear();
                        listView_BuildTable.Clear();
                        button_DBConn.Text = "连  接";
                        label_DBConn.Text = "无连接！";
                        ConnectionString = "";
                        DataBaseString = "";
                        DataBaseType = 0;
                        ConnNamespace = "";
                        ConnDBName = "";
                        PackageName = "";
                        button_Generator.Enabled = false;
                    }
                }
                else
                {
                    ListViewInit();
                    button_DBConn.Text = "无连接！";
                    var formConn = new Form_DBConn();
                    if (formConn.ShowDialog() == DialogResult.Yes)
                    {
                        if (!string.IsNullOrWhiteSpace(ConnectionString) && !string.IsNullOrWhiteSpace(DataBaseString))
                        {
                            #region 验证连接

                            if (DataBaseType == 1)
                            {
                                DataBaseDALProp = new MysqlDataBaseDAL();
                            }
                            else
                            {
                                MessageBox.Show("暂时不支持的数据库类型！");
                                return;
                            }
                            List<TableInfo> tableInfos = DataBaseDALProp.GetAllTableName(ConnectionString,
                                DataBaseString);
                            if (tableInfos == null || tableInfos.Count <= 0)
                            {
                                MessageBox.Show("没有找到任何表！");
                                return;
                            }

                            #endregion

                            ListViewItem listViewItem = null;
                            foreach (TableInfo tableInfo in tableInfos)
                            {
                                listViewItem = new ListViewItem();
                                listViewItem.SubItems.Add(tableInfo.TABLE_NAME);
                                listView_SourceTable.Items.Add(listViewItem);
                            }
                            label_DBConn.Text = "已连接数据库：" + DataBaseString + "！";
                            button_DBConn.Text = "断  开";
                            button_Generator.Enabled = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("异常：" + ex.Message);
            }
        }

        private void button_Generator_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(ConnectionString) || string.IsNullOrWhiteSpace(DataBaseString))
            {
                MessageBox.Show("连接数据库以后再操作！");
                return;
            }
            if (listView_BuildTable.Items.Count <= 0)
            {
                MessageBox.Show("没有选中任何表！");
                return;
            }
            int SelectCount = listView_BuildTable.Items.Count;
            progressBar_Generator.Maximum = SelectCount;
            progressBar_Generator.Value = 0;
            button_Generator.Enabled = false;
            List<TableInfo> tableInfos = DataBaseDALProp.GetAllTableName(ConnectionString, DataBaseString);
            for (int index = tableInfos.Count - 1; index >= 0; index--)
            {
                bool IsExist =
                    listView_BuildTable.Items.Cast<ListViewItem>()
                        .Any(listViewItem => tableInfos[index].TABLE_NAME.Equals(listViewItem.SubItems[1].Text));
                if (!IsExist)
                    tableInfos.RemoveAt(index);
            }
            backgroundWorker_Generator.RunWorkerAsync(tableInfos);
        }

        private void button_ToSingleRight_Click(object sender, EventArgs e)
        {
            ListView.SelectedListViewItemCollection selectedListViewItemCollection = listView_SourceTable.SelectedItems;
            if (selectedListViewItemCollection == null || selectedListViewItemCollection.Count <= 0)
            {
                MessageBox.Show("没有选中任何行！");
                return;
            }
            int SelectCount = selectedListViewItemCollection.Count;
            for (int index = SelectCount - 1; index >= 0; index--)
            {
                ListViewItem listViewItem = selectedListViewItemCollection[index];
                listView_SourceTable.Items.RemoveAt(listViewItem.Index);
                listView_BuildTable.Items.Add(listViewItem);
            }
        }

        private void button_ToAllRight_Click(object sender, EventArgs e)
        {
            if (listView_SourceTable.Items.Count <= 0)
            {
                MessageBox.Show("没有选中任何行！");
                return;
            }
            int SelectCount = listView_SourceTable.Items.Count;
            for (int index = SelectCount - 1; index >= 0; index--)
            {
                ListViewItem listViewItem = listView_SourceTable.Items[index];
                listView_SourceTable.Items.RemoveAt(listViewItem.Index);
                listView_BuildTable.Items.Add(listViewItem);
            }
        }

        private void button_ToSingleLeft_Click(object sender, EventArgs e)
        {
            ListView.SelectedListViewItemCollection selectedListViewItemCollection = listView_BuildTable.SelectedItems;
            if (selectedListViewItemCollection == null || selectedListViewItemCollection.Count <= 0)
            {
                MessageBox.Show("没有选中任何行！");
                return;
            }
            int SelectCount = selectedListViewItemCollection.Count;
            for (int index = SelectCount - 1; index >= 0; index--)
            {
                ListViewItem listViewItem = selectedListViewItemCollection[index];
                listView_BuildTable.Items.RemoveAt(listViewItem.Index);
                listView_SourceTable.Items.Add(listViewItem);
            }
        }

        private void button_ToAllLeft_Click(object sender, EventArgs e)
        {
            if (listView_BuildTable.Items.Count <= 0)
            {
                MessageBox.Show("没有选中任何行！");
                return;
            }
            int SelectCount = listView_BuildTable.Items.Count;
            for (int index = SelectCount - 1; index >= 0; index--)
            {
                ListViewItem listViewItem = listView_BuildTable.Items[index];
                listView_BuildTable.Items.RemoveAt(listViewItem.Index);
                listView_SourceTable.Items.Add(listViewItem);
            }
        }

        private void ListViewInit()
        {
            listView_SourceTable.Clear();
            listView_BuildTable.Clear();
            var il = new ImageList();
            il.ImageSize = new Size(1, 20);
            listView_SourceTable.HeaderStyle = ColumnHeaderStyle.Nonclickable;
            listView_SourceTable.Columns.Add("", 1, HorizontalAlignment.Center);
            listView_SourceTable.Columns.Add("表名", 293, HorizontalAlignment.Left);
            listView_SourceTable.HideSelection = false;
            listView_SourceTable.SmallImageList = il;
            listView_BuildTable.HeaderStyle = ColumnHeaderStyle.Nonclickable;
            listView_BuildTable.Columns.Add("", 1, HorizontalAlignment.Center);
            listView_BuildTable.Columns.Add("表名", 293, HorizontalAlignment.Left);
            listView_BuildTable.HideSelection = false;
            listView_BuildTable.SmallImageList = il;
        }

        /// <summary>
        ///     生成Struct
        /// </summary>
        private bool GeneratorStruct(TableInfo tableInfo, List<ColumnInfo> columnInfos)
        {
            if (DataBaseType == 1)
                return GeneratorMySqlStruct(tableInfo, columnInfos);
            return false;
        }

        /// <summary>
        ///     生成mysql结构体
        /// </summary>
        private bool GeneratorMySqlStruct(TableInfo tableInfo, List<ColumnInfo> columnInfos)
        {
            try
            {
                int initvalue = 0;
                bool IsExistTimeType = false;
                bool IsPK = false;
                var ModelData = new StringBuilder();

                #region PK

                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    string tmpType = GetFileType(columnInfo.DATA_TYPE);
                    if (tmpType.Equals("time.Time"))
                        IsExistTimeType = true;
                    if (columnInfo.COLUMN_KEY.Equals("PRI"))
                        IsPK = true;
                }
                if (!IsPK)
                {
                    Log.ErrorFormat("【GeneratorMySqlStruct.PK】表：{0}，没有主键", tableInfo.TABLE_NAME);
                    return false;
                }
                string StructName = UtilityMethod.ToTitleCase(tableInfo.TABLE_NAME);
                string LowName = ToTitleLow(tableInfo.TABLE_NAME);

                #endregion

                #region Package

                ModelData.AppendLine(string.Format("package {0}", PackageName));
                ModelData.AppendLine("");
                ModelData.AppendLine("import (");
                ModelData.AppendLine("\t\"database/sql\"");
                ModelData.AppendLine("\t\"errors\"");
                ModelData.AppendLine("\t\"gitee.com/ha666/golibs\"");
                if (IsExistTimeType)
                {
                    ModelData.AppendLine("\t\"time\"");
                }
                if (!string.IsNullOrWhiteSpace(ConnNamespace))
                {
                    ModelData.AppendLine(string.Format("\t\"{0}\"", ConnNamespace));
                }
                ModelData.AppendLine(")");

                #endregion

                #region Struct

                ModelData.AppendLine("");
                if (!string.IsNullOrWhiteSpace(tableInfo.TABLE_COMMENT))
                    ModelData.AppendLine(string.Format("//{0}", tableInfo.TABLE_COMMENT));
                ModelData.AppendLine(string.Format("type {0} struct {{", StructName));
                bool ReturnPK = false;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                    {
                        ReturnPK = true;
                    }
                    ModelData.AppendLine(string.Format("\t{0}\t{1}{2}", columnInfo.COLUMN_NAME_Case,
                        GetFileType(columnInfo.DATA_TYPE),
                        !string.IsNullOrWhiteSpace(columnInfo.COLUMN_COMMENT) ? "\t//" + columnInfo.COLUMN_COMMENT : ""));
                }
                ModelData.Append("}");
                ModelData.AppendLine("");

                #endregion

                #region IndexList

                List<IndexInfo> indexInfos = DataBaseDALProp.GetAllIndexs(ConnectionString, DataBaseString, tableInfo.TABLE_NAME);
                var indexs = new Dictionary<string, List<IndexInfo>>();
                foreach (IndexInfo indexInfo in indexInfos)
                {
                    if (!indexs.ContainsKey(indexInfo.INDEX_NAME))
                    {
                        indexs.Add(indexInfo.INDEX_NAME, new List<IndexInfo> { indexInfo });
                    }
                    else
                    {
                        indexs[indexInfo.INDEX_NAME].Add(indexInfo);
                    }
                }

                int PKCount = 0;
                ColumnInfo PKColumnInfo = columnInfos[0];
                foreach (var keyValuePair in indexs)
                {
                    if (keyValuePair.Key.Contains("PRIMARY"))
                    {
                        foreach (IndexInfo valuePair in keyValuePair.Value)
                        {
                            ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                            if (tmpInfo == null)
                            {
                                Log.ErrorFormat("【GeneratorMySqlStruct.In】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                                continue;
                            }
                            PKCount += 1;
                            PKColumnInfo = tmpInfo;
                        }
                    }
                }

                #endregion

                #region Exist

                ModelData.AppendLine("");
                ModelData.Append(string.Format("func Exist{0}(", StructName));
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(columnInfo.COLUMN_NAME).Append(" ").Append(GetFileType(columnInfo.DATA_TYPE));
                    initvalue++;
                }
                ModelData.AppendLine(") (bool, error) {");
                ModelData.Append(string.Format("\trows, err := {0}.Query(\"select count(0) Count from {1} where ",
                    ConnDBName, tableInfo.TABLE_NAME));
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(" and ");
                    ModelData.AppendFormat("{0}=?", columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.Append("\", ");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.AppendFormat("{0}", columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.AppendLine(")");
                ModelData.AppendLine("\tdefer rows.Close()");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine("\t\treturn false, err");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\tcount := 0");
                ModelData.AppendLine("\tif rows.Next() {");
                ModelData.AppendLine("\t\terr = rows.Scan(&count)");
                ModelData.AppendLine("\t\tif err != nil {");
                ModelData.AppendLine("\t\t\treturn false, err");
                ModelData.AppendLine("\t\t}");
                ModelData.AppendLine("\t\treturn count > 0, nil");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\treturn false, nil");
                ModelData.AppendLine("}");

                #endregion

                #region Insert

                ModelData.AppendLine("");
                ModelData.Append(string.Format("func Insert{0}({1} *{0}) (", StructName, tableInfo.TABLE_NAME));
                ModelData.AppendLine(string.Format("{0}, error) {{", ReturnPK ? "int64" : "bool"));
                ModelData.AppendFormat("\tresult, err := {0}.Exec(\"insert into {1}(", ConnDBName, tableInfo.TABLE_NAME);
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(",");
                    ModelData.Append(columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.Append(") values(");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(",");
                    ModelData.Append("?");
                    initvalue++;
                }
                ModelData.Append(")\", ");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(",");
                    ModelData.Append(tableInfo.TABLE_NAME).Append(".").Append(columnInfo.COLUMN_NAME_Case);
                    initvalue++;
                }
                ModelData.AppendLine(")");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine(string.Format("\t\treturn {0}, err", ReturnPK ? "-1" : "false"));
                ModelData.AppendLine("\t}");
                if (ReturnPK)
                {
                    ModelData.AppendLine("\treturn result.LastInsertId()");
                }
                else
                {
                    ModelData.AppendLine("\taffected, err := result.RowsAffected()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine(string.Format("\t\treturn {0}, err", ReturnPK ? "-1" : "false"));
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine(string.Format("\treturn {0}, nil", ReturnPK ? "affected" : "affected > 0"));
                }
                ModelData.AppendLine("}");

                #endregion

                #region Update

                ModelData.AppendLine("");
                ModelData.AppendLine(string.Format("func Update{0}({1} *{0}) (bool, error) {{", StructName,
                    tableInfo.TABLE_NAME));
                ModelData.AppendFormat("\tresult, err := {0}.Exec(\"update {1} set ", ConnDBName, tableInfo.TABLE_NAME);
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(columnInfo.COLUMN_NAME).Append("=?");
                    initvalue++;
                }
                ModelData.Append(" where ");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(" and ");
                    ModelData.Append(columnInfo.COLUMN_NAME).Append("=?");
                    initvalue++;
                }
                ModelData.Append("\", ");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(tableInfo.TABLE_NAME).Append(".").Append(columnInfo.COLUMN_NAME_Case);
                    initvalue++;
                }
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    ModelData.Append(", ");
                    ModelData.Append(tableInfo.TABLE_NAME).Append(".").Append(columnInfo.COLUMN_NAME_Case);
                    initvalue++;
                }
                ModelData.AppendLine(")");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine("\t\treturn false, err");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\taffected, err := result.RowsAffected()");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine("\t\treturn false, err");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\treturn affected > 0, nil");
                ModelData.AppendLine("}");

                #endregion

                #region InsertUpdate

                bool is_auto_incre = false;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                    {
                        is_auto_incre = true;
                        break;
                    }
                }
                if (!is_auto_incre)
                {
                    ModelData.AppendLine("");
                    ModelData.Append(string.Format("func InsertUpdate{0}({1} *{0}) (", StructName, tableInfo.TABLE_NAME));
                    ModelData.AppendLine("bool, error) {");
                    ModelData.AppendFormat("\tresult, err := {0}.Exec(\"insert into {1}(", ConnDBName,
                        tableInfo.TABLE_NAME);
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                        {
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(",");
                        ModelData.Append(columnInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.Append(") values(");
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) && columnInfo.EXTRA.Contains("auto_increment"))
                        {
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(",");
                        ModelData.Append("?");
                        initvalue++;
                    }
                    ModelData.Append(") ON DUPLICATE KEY UPDATE ");
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (columnInfo.COLUMN_KEY.Equals("PRI"))
                        {
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(",");
                        ModelData.AppendFormat("{0}=?", columnInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.Append("\", ");
                    initvalue = 0;
                    for (int i1 = 0; i1 < 2; i1++)
                    {
                        foreach (ColumnInfo columnInfo in columnInfos)
                        {
                            if (i1 > 0 && columnInfo.COLUMN_KEY.Equals("PRI"))
                            {
                                continue;
                            }
                            if (!string.IsNullOrWhiteSpace(columnInfo.EXTRA) &&
                                columnInfo.EXTRA.Contains("auto_increment"))
                            {
                                continue;
                            }
                            if (initvalue > 0)
                                ModelData.Append(",");
                            ModelData.Append(tableInfo.TABLE_NAME).Append(".").Append(columnInfo.COLUMN_NAME_Case);
                            initvalue++;
                        }
                    }
                    ModelData.AppendLine(")");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine("\t\treturn false, err");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\taffected, err := result.RowsAffected()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine("\t\treturn false, err");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\treturn affected > 0, nil");
                    ModelData.AppendLine("}");
                }

                #endregion

                #region Delete
                {

                    ModelData.AppendLine("");
                    ModelData.AppendFormat("func Delete{0}(", StructName);
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                        {
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.Append(columnInfo.COLUMN_NAME).Append(" ").Append(GetFileType(columnInfo.DATA_TYPE));
                        initvalue++;
                    }
                    ModelData.AppendLine(") (bool, error) {");
                    ModelData.AppendFormat("\tresult, err := {0}.Exec(\"delete from {1} ", ConnDBName, tableInfo.TABLE_NAME);
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                        {
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(" and ");
                        ModelData.Append(columnInfo.COLUMN_NAME).Append("=?");
                        initvalue++;
                    }
                    ModelData.Append("\"");
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                        {
                            continue;
                        }
                        ModelData.Append(", ");
                        ModelData.Append(columnInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.AppendLine(")");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine("\t\treturn false, err");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\taffected, err := result.RowsAffected()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine("\t\treturn false, err");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\treturn affected > 0, nil");
                    ModelData.AppendLine("}");

                }
                #endregion

                #region Deletes
                {

                    if (PKCount == 1)
                    {
                        ModelData.AppendLine("");
                        ModelData.AppendLine(string.Format("// 根据{0}数组删除{1}记录", PKColumnInfo.COLUMN_COMMENT, tableInfo.TABLE_COMMENT));
                        ModelData.AppendLine(string.Format("func Delete{0}In{1}({1}s []{2}) (count int64, err error) {{", StructName, PKColumnInfo.COLUMN_NAME, GetFileType(PKColumnInfo.DATA_TYPE)));
                        ModelData.AppendLine(string.Format("\tif len({0}s) <= 0 {{", PKColumnInfo.COLUMN_NAME));
                        ModelData.AppendLine(string.Format("\t\treturn count, errors.New(\"{0}s is empty\")", PKColumnInfo.COLUMN_NAME));
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine(string.Format("\tif len({0}s) > 20 {{", PKColumnInfo.COLUMN_NAME));
                        ModelData.AppendLine("\t\treturn count, errors.New(\"limit 20\")");
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine("\tsql_str := golibs.NewStringBuilder()");
                        ModelData.AppendLine(string.Format("\tsql_str.Append(\"delete from {0}\")", tableInfo.TABLE_NAME));
                        ModelData.AppendLine(string.Format("\tsql_str.Append(\" where {0} in(\")", PKColumnInfo.COLUMN_NAME));
                        ModelData.AppendLine(string.Format("\tfor i := 0; i < len({0}s); i++ {{", PKColumnInfo.COLUMN_NAME));
                        ModelData.AppendLine("\t\tif i > 0 {");
                        ModelData.AppendLine("\t\t\tsql_str.Append(\", \")");
                        ModelData.AppendLine("\t\t}");
                        ModelData.AppendLine("\t\tsql_str.Append(\" ? \")");
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine("\tsql_str.Append(\")\")");
                        ModelData.AppendLine(string.Format("\tswitch len({0}s) {{", PKColumnInfo.COLUMN_NAME));
                        for (int i = 1; i <= 20; i++)
                        {
                            ModelData.AppendLine(string.Format("\tcase {0}:", i));
                            ModelData.AppendFormat("\t\trows, err = {0}.Exec(sql_str.ToString()", ConnDBName);
                            for (int j = 0; j < i; j++)
                            {
                                ModelData.AppendFormat(", {0}s[{1}]", PKColumnInfo.COLUMN_NAME, j);
                            }
                            ModelData.AppendLine(")");
                        }
                        ModelData.AppendLine("\tdefault:");
                        ModelData.AppendLine("\t\treturn count, errors.New(\"limit 20\")");
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine("\tif err != nil {");
                        ModelData.AppendLine("\t\treturn count, err");
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine("\taffected, err := result.RowsAffected()");
                        ModelData.AppendLine("\tif err != nil {");
                        ModelData.AppendLine("\t\treturn count, err");
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine("\treturn affected, nil");
                        ModelData.AppendLine("}");
                    }

                }
                #endregion

                #region Get

                ModelData.AppendLine("");
                ModelData.Append(string.Format("func Get{0}(", StructName));
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(columnInfo.COLUMN_NAME).Append(" ").Append(GetFileType(columnInfo.DATA_TYPE));
                    initvalue++;
                }
                ModelData.AppendLine(string.Format(") ({0} {1}, err error) {{", tableInfo.TABLE_NAME, StructName));
                ModelData.AppendFormat("\trows, err := {0}.Query(\"select ", ConnDBName);
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.Append(string.Format(" from {0} where ", tableInfo.TABLE_NAME));
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(" and ");
                    ModelData.AppendFormat("{0}=?", columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.Append("\", ");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (!columnInfo.COLUMN_KEY.Equals("PRI"))
                    {
                        continue;
                    }
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.AppendFormat("{0}", columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.AppendLine(")");
                ModelData.AppendLine("\tdefer rows.Close()");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine(string.Format("\t\treturn {0}, err", tableInfo.TABLE_NAME));
                ModelData.AppendLine("\t}");
                ModelData.AppendLine(string.Format("\t{0}s, err := _{1}RowsToArray(rows)", tableInfo.TABLE_NAME,
                    StructName));
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine(string.Format("\t\treturn {0}, err", tableInfo.TABLE_NAME));
                ModelData.AppendLine("\t}");
                ModelData.AppendLine(string.Format("\tif len({0}s) <= 0 {{", tableInfo.TABLE_NAME));
                ModelData.AppendLine(string.Format("\t\treturn {0}, err", tableInfo.TABLE_NAME));
                ModelData.AppendLine("\t}");
                ModelData.AppendLine(string.Format("\treturn {0}s[0], nil", tableInfo.TABLE_NAME));
                ModelData.AppendLine("}");

                #endregion

                #region In

                if (PKCount == 1)
                {
                    ModelData.AppendLine("");
                    ModelData.AppendLine(string.Format("// 根据{0}数组查询{1}列表", PKColumnInfo.COLUMN_COMMENT, tableInfo.TABLE_COMMENT));
                    ModelData.AppendLine(string.Format("func Get{0}In{1}({1}s []{2}) ({3}s []{0}, err error) {{", StructName, PKColumnInfo.COLUMN_NAME, GetFileType(PKColumnInfo.DATA_TYPE),tableInfo.TABLE_NAME));
                    ModelData.AppendLine(string.Format("\tif len({0}s) <= 0 {{", PKColumnInfo.COLUMN_NAME));
                    ModelData.AppendLine(string.Format("\t\treturn {0}s, errors.New(\"{1}s is empty\")", tableInfo.TABLE_NAME, PKColumnInfo.COLUMN_NAME));
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine(string.Format("\tif len({0}s) > 20 {{", PKColumnInfo.COLUMN_NAME));
                    ModelData.AppendLine(string.Format("\t\treturn {0}s, errors.New(\"limit 20\")", tableInfo.TABLE_NAME));
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\tsql_str := golibs.NewStringBuilder()");
                    ModelData.Append("\tsql_str.Append(\"select ");
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.Append(columnInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.AppendLine(" from \")");
                    ModelData.AppendLine(string.Format("\tsql_str.Append(\"{0}\")",tableInfo.TABLE_NAME));
                    ModelData.AppendLine(string.Format("\tsql_str.Append(\" where {0} in(\")",PKColumnInfo.COLUMN_NAME));
                    ModelData.AppendLine(string.Format("\tfor i := 0; i < len({0}s); i++ {{",PKColumnInfo.COLUMN_NAME));
                    ModelData.AppendLine("\t\tif i > 0 {");
                    ModelData.AppendLine("\t\t\tsql_str.Append(\", \")");
                    ModelData.AppendLine("\t\t}");
                    ModelData.AppendLine("\t\tsql_str.Append(\" ? \")");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\tsql_str.Append(\")\")");
                    ModelData.AppendLine("\tvar rows *sql.Rows");
                    ModelData.AppendLine(string.Format("\tswitch len({0}s) {{",PKColumnInfo.COLUMN_NAME));
                    for (int i = 1; i <= 20; i++)
                    {
                        ModelData.AppendLine(string.Format("\tcase {0}:", i));
                        ModelData.AppendFormat("\t\trows, err = {0}.Query(sql_str.ToString()", ConnDBName);
                        for (int j = 0; j < i; j++)
                        {
                            ModelData.AppendFormat(", {0}s[{1}]", PKColumnInfo.COLUMN_NAME, j);
                        }
                        ModelData.AppendLine(")");
                    }
                    ModelData.AppendLine("\tdefault:");
                    ModelData.AppendLine(string.Format("\t\treturn {0}s, errors.New(\"limit 20\")", tableInfo.TABLE_NAME));
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\tdefer rows.Close()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine(string.Format("\t\treturn {0}s, err", tableInfo.TABLE_NAME));
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine(string.Format("\treturn _{0}RowsToArray(rows)", StructName));
                    ModelData.AppendLine("}");
                }

                #endregion

                #region Index

                foreach (var keyValuePair in indexs)
                {
                    if (keyValuePair.Key.Contains("PRIMARY"))
                    {
                        continue;
                    }
                    if (keyValuePair.Value.Count <= 0)
                    {
                        continue;
                    }
                    ModelData.AppendLine("");
                    ModelData.AppendLine(string.Format("// {0}", keyValuePair.Value[0].INDEX_NAME));
                    ModelData.Append(string.Format("func Get{0}By", StructName));
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        ModelData.Append(tmpInfo.COLUMN_NAME);
                    }
                    ModelData.Append("(");
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.AppendFormat("{0} {1}", tmpInfo.COLUMN_NAME, GetFileType(tmpInfo.DATA_TYPE));
                        initvalue++;
                    }
                    ModelData.AppendLine(string.Format(") ({0}{1}{2}, err error) {{", tableInfo.TABLE_NAME,
                        keyValuePair.Value[0].NON_UNIQUE > 0 ? "s []" : " ", StructName));
                    ModelData.AppendFormat("\trows, err := {0}.Query(\"select ", ConnDBName);
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.Append(columnInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.AppendFormat(" from {0} force index({1}) where ", tableInfo.TABLE_NAME, keyValuePair.Value[0].INDEX_NAME);
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                        {
                            ModelData.Append(" and ");
                        }
                        ModelData.AppendFormat("{0}=?", tmpInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.Append("\",");
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                        {
                            ModelData.Append(", ");
                        }
                        ModelData.AppendFormat("{0}", tmpInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.AppendLine(")");
                    ModelData.AppendLine("\tdefer rows.Close()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine(string.Format("\t\treturn {0}{1}, err", tableInfo.TABLE_NAME,
                        keyValuePair.Value[0].NON_UNIQUE > 0 ? "s" : ""));
                    ModelData.AppendLine("\t}");
                    if (keyValuePair.Value[0].NON_UNIQUE == 0)
                    {
                        ModelData.AppendLine(string.Format("\t{0}s, err := _{1}RowsToArray(rows)", tableInfo.TABLE_NAME,
                            StructName));
                        ModelData.AppendLine("\tif err != nil {");
                        ModelData.AppendLine(string.Format("\t\treturn {0}, err", tableInfo.TABLE_NAME));
                        ModelData.AppendLine("\t}");
                        ModelData.AppendLine(string.Format("\treturn {0}s[0], nil", tableInfo.TABLE_NAME));
                    }
                    else
                    {
                        ModelData.AppendLine(string.Format("\treturn _{0}RowsToArray(rows)", StructName));
                    }
                    ModelData.AppendLine("}");
                }
                
                #endregion

                #region Count

                #region 查询总记录数
                ModelData.AppendLine("");
                ModelData.AppendLine(string.Format("func Get{0}RowCount() (count int, err error) {{", StructName));
                ModelData.AppendLine(string.Format("\trows, err := {0}.Query(\"select count(0) Count from {1}\")",
                    ConnDBName, tableInfo.TABLE_NAME));
                ModelData.AppendLine("\tdefer rows.Close()");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine("\t\treturn -1, err");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\tif rows.Next() {");
                ModelData.AppendLine("\t\terr = rows.Scan(&count)");
                ModelData.AppendLine("\t\tif err != nil {");
                ModelData.AppendLine("\t\t\treturn -1, err");
                ModelData.AppendLine("\t\t}");
                ModelData.AppendLine("\t\treturn count, nil");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\treturn -1, nil");
                ModelData.AppendLine("}");
                #endregion

                #region Index

                #region 循环处理各分组

                foreach (var keyValuePair in indexs)
                {
                    if (keyValuePair.Key.Contains("PK_"))
                        continue;
                    if (keyValuePair.Value[0].NON_UNIQUE == 0)
                    {
                        continue;
                    }
                    ModelData.AppendLine("");
                    ModelData.AppendLine(string.Format("// {0}", keyValuePair.Value[0].INDEX_NAME));
                    ModelData.Append(string.Format("func Get{0}RowCountBy", StructName));
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ModelData.Append(valuePair.COLUMN_NAME);
                    }
                    ModelData.Append("(");
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.Count_INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.AppendFormat("{0} {1}", tmpInfo.COLUMN_NAME, GetFileType(tmpInfo.DATA_TYPE));
                        initvalue++;
                    }
                    ModelData.AppendLine(") (count int, err error) {");
                    ModelData.AppendFormat("\trows, err := {0}.Query(\"select count(0) Count from {1} force index({2}) where ", ConnDBName, tableInfo.TABLE_NAME, keyValuePair.Value[0].INDEX_NAME);
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.Count_INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                        {
                            ModelData.Append(" and ");
                        }
                        ModelData.AppendFormat("{0}=?", tmpInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.Append("\",");
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.Count_INDEX】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                        {
                            ModelData.Append(", ");
                        }
                        ModelData.AppendFormat("{0}", tmpInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.AppendLine(")");
                    ModelData.AppendLine("\tdefer rows.Close()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine("\t\treturn -1, err");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\tif rows.Next() {");
                    ModelData.AppendLine("\t\terr = rows.Scan(&count)");
                    ModelData.AppendLine("\t\tif err != nil {");
                    ModelData.AppendLine("\t\t\treturn -1, err");
                    ModelData.AppendLine("\t\t}");
                    ModelData.AppendLine("\t\treturn count, nil");
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine("\treturn -1, nil");
                    ModelData.AppendLine("}");
                }

                #endregion

                #endregion

                #endregion

                #region All

                ModelData.AppendLine("");
                ModelData.Append(string.Format("func Get{0}All()", StructName));
                ModelData.AppendLine(string.Format("({0}s []{1}, err error) {{", tableInfo.TABLE_NAME, StructName));
                ModelData.AppendFormat("\trows, err := {0}.Query(\"select ", ConnDBName);
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.AppendFormat(" from {0}", tableInfo.TABLE_NAME);
                ModelData.AppendLine("\")");
                ModelData.AppendLine("\tdefer rows.Close()");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine(string.Format("\t\treturn {0}s, err", tableInfo.TABLE_NAME));
                ModelData.AppendLine("\t}");
                ModelData.AppendLine(string.Format("\treturn _{0}RowsToArray(rows)", StructName));
                ModelData.AppendLine("}");

                #endregion

                #region RowList

                #region NonIndex

                ModelData.AppendLine("");
                ModelData.Append(string.Format("func Get{0}RowList", StructName));
                ModelData.Append("(PageIndex, PageSize int) (");
                ModelData.AppendLine(string.Format("{0}s []{1}, err error) {{", tableInfo.TABLE_NAME, StructName));
                ModelData.AppendFormat("\trows, err := {0}.Query(\"select ", ConnDBName);
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.Append(columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.AppendFormat(" from {0}", tableInfo.TABLE_NAME);
                ModelData.Append(" limit ?,?\"");
                ModelData.Append(", (PageIndex-1)*PageSize, PageSize");
                ModelData.AppendLine(")");
                ModelData.AppendLine("\tdefer rows.Close()");
                ModelData.AppendLine("\tif err != nil {");
                ModelData.AppendLine(string.Format("\t\treturn {0}s, err", tableInfo.TABLE_NAME));
                ModelData.AppendLine("\t}");
                ModelData.AppendLine(string.Format("\treturn _{0}RowsToArray(rows)", StructName));
                ModelData.AppendLine("}");

                #endregion

                #region Index

                #region 循环处理各分组

                foreach (var keyValuePair in indexs)
                {
                    if (keyValuePair.Key.Contains("PK_"))
                        continue;
                    if (keyValuePair.Value[0].NON_UNIQUE == 0)
                    {
                        continue;
                    }
                    ModelData.AppendLine("");
                    ModelData.AppendLine(string.Format("// {0}", keyValuePair.Value[0].INDEX_NAME));
                    ModelData.Append(string.Format("func Get{0}RowListBy", StructName));
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ModelData.Append(valuePair.COLUMN_NAME);
                    }
                    ModelData.Append("(");
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.Pager】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.Append(valuePair.COLUMN_NAME).Append(" ").Append(GetFileType(tmpInfo.DATA_TYPE));
                        initvalue++;
                    }
                    ModelData.Append(", PageIndex, PageSize int) (");
                    ModelData.AppendLine(string.Format("{0}s []{1}, err error) {{", tableInfo.TABLE_NAME, StructName));
                    ModelData.AppendFormat("\trows, err := {0}.Query(\"select ",ConnDBName);
                    initvalue = 0;
                    foreach (ColumnInfo columnInfo in columnInfos)
                    {
                        if (initvalue > 0)
                            ModelData.Append(", ");
                        ModelData.Append(columnInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.AppendFormat(" from {0} force index({1}) where ", tableInfo.TABLE_NAME, keyValuePair.Value[0].INDEX_NAME);
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.Pager】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                        {
                            ModelData.Append(" and ");
                        }
                        ModelData.AppendFormat("{0}=?", tmpInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.Append(" limit ?,?\",");
                    initvalue = 0;
                    foreach (IndexInfo valuePair in keyValuePair.Value)
                    {
                        ColumnInfo tmpInfo = GetColumnByName(columnInfos, valuePair.COLUMN_NAME);
                        if (tmpInfo == null)
                        {
                            Log.ErrorFormat("【GeneratorMySqlStruct.Pager】根据名字{0}没有找到字段信息", valuePair.COLUMN_NAME);
                            continue;
                        }
                        if (initvalue > 0)
                        {
                            ModelData.Append(", ");
                        }
                        ModelData.AppendFormat("{0}", tmpInfo.COLUMN_NAME);
                        initvalue++;
                    }
                    ModelData.Append(", (PageIndex-1)*PageSize, PageSize");
                    ModelData.AppendLine(")");
                    ModelData.AppendLine("\tdefer rows.Close()");
                    ModelData.AppendLine("\tif err != nil {");
                    ModelData.AppendLine(string.Format("\t\treturn {0}s, err", tableInfo.TABLE_NAME));
                    ModelData.AppendLine("\t}");
                    ModelData.AppendLine(string.Format("\treturn _{0}RowsToArray(rows)", StructName));
                    ModelData.AppendLine("}");
                }

                #endregion

                #endregion

                #endregion

                #region RowToStruct

                ModelData.AppendLine("");
                ModelData.AppendLine(string.Format("func _{0}RowsToArray(rows *sql.Rows) (models []{0}, err error) {{",
                    StructName));
                ModelData.AppendLine("\tfor rows.Next() {");

                ModelData.AppendLine(string.Format("\t\tmodel := {0}{{}}", StructName));
                ModelData.Append("\t\terr = rows.Scan(");
                initvalue = 0;
                foreach (ColumnInfo columnInfo in columnInfos)
                {
                    if (initvalue > 0)
                        ModelData.Append(", ");
                    ModelData.AppendFormat("&model.{0}", columnInfo.COLUMN_NAME);
                    initvalue++;
                }
                ModelData.AppendLine(")");
                ModelData.AppendLine("\t\tif err != nil {");
                ModelData.AppendLine("\t\t\treturn models, err");
                ModelData.AppendLine("\t\t}");
                ModelData.AppendLine("\t\tmodels = append(models, model)");
                ModelData.AppendLine("\t}");
                ModelData.AppendLine("\treturn models, err");
                ModelData.AppendLine("}");

                #endregion

                File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + TemplatesPath + "//" + LowName + ".go",
                    ModelData.ToString(), Encoding.UTF8);
                return true;
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("【GeneratorMySqlStruct】ex：{0}", ex);
            }
            return false;
        }

        /// <summary>
        ///     根据字段名查找字段信息
        /// </summary>
        private ColumnInfo GetColumnByName(List<ColumnInfo> columnInfos, string columnName)
        {
            foreach (ColumnInfo columnInfo in columnInfos)
            {
                if (columnInfo.COLUMN_NAME.Equals(columnName))
                    return columnInfo;
            }
            return null;
        }

        /// <summary>
        ///     转首字母小写
        /// </summary>
        private static string ToTitleLow(string source)
        {
            char last_char = '&';
            var data = new StringBuilder();
            foreach (char c1 in source)
            {
                if (c1 > 64 && c1 < 91)
                {
                    if (last_char != '_' && data.Length > 0)
                    {
                        data.Append("_");
                        last_char = '_';
                    }
                    data.Append(c1.ToString().ToLower());
                    last_char = c1;
                }
                else
                {
                    data.Append(c1.ToString());
                    last_char = c1;
                }
            }
            return data.ToString();
        }

        /// <summary>
        ///     根据db类型转成golang类型
        /// </summary>
        private string GetFileType(string FieldType)
        {
            string TypeResult = "";
            switch (FieldType)
            {
                case "bit":
                    TypeResult = "bool";
                    break;
                case "tinyint":
                    TypeResult = "int8";
                    break;
                case "smallint":
                    TypeResult = "int16";
                    break;
                case "int":
                    TypeResult = "int";
                    break;
                case "bigint":
                    TypeResult = "int64";
                    break;
                case "float":
                case "decimal":
                case "double":
                case "numeric":
                    TypeResult = "float64";
                    break;
                case "char":
                case "nchar":
                case "varchar":
                case "nvarchar":
                case "text":
                case "longtext":
                case "mediumtext":
                    TypeResult = "string";
                    break;
                case "blob":
                case "longblob":
                case "mediumblob":
                case "tinyblob":
                    TypeResult = "[]byte";
                    break;
                case "date":
                case "datetime":
                case "datetime2":
                    TypeResult = "time.Time";
                    break;
            }
            return TypeResult;
        }

        private void Form_Main_Shown(object sender, EventArgs e)
        {
            ListViewInit();
            button_Generator.Enabled = false;
        }

        private void backgroundWorker_Generator_DoWork(object sender, DoWorkEventArgs e)
        {
            var tableInfos = e.Argument as List<TableInfo>;
            try
            {
                int Count = tableInfos.Count;
                int index = 1;
                while (index <= Count)
                {
                    string tableName = tableInfos[index - 1].TABLE_NAME;
                    Log.Info("开始执行表：" + tableName);
                    backgroundWorker_Generator.ReportProgress(index, "正在执行表：" + tableName);
                    Thread.Sleep(500);

                    #region 根据表名查询所有的列信息

                    List<ColumnInfo> columnInfos = DataBaseDALProp.GetAllColumns(ConnectionString, DataBaseString,
                        tableName);

                    #endregion

                    Log.Info("表信息加载完成：" + tableName);

                    #region 生成struct

                    GeneratorStruct(tableInfos[index - 1], columnInfos);
                    Log.Info("表执行完成：" + tableName);

                    #endregion

                    index++;
                }
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("【Generator_DoWork】ex：{0}", ex);
            }
        }

        private void backgroundWorker_Generator_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar_Generator.Value = e.ProgressPercentage;
            //toolStripStatusLabel_Status.Text = e.UserState.ToString();
        }

        private void backgroundWorker_Generator_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            button_Generator.Enabled = true;
            //toolStripStatusLabel_Status.Text = "";
            progressBar_Generator.Value = 0;
        }

        private void Form_Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            Application.Exit();
        }
    }
}